Shader "Perlin/Improved2"
{
	Properties
	{
		_PermTex2D("PermTex2D", 2D) = "white" {}
		_GradTex2D("GradTex2D", 2D) = "white" {}
		_PermTexSize("PermTexSize", Float) = 256

		_UVScale("UVScale", Float) = 6.0
		_UVShift("UVShift", Float) = 0.0
		_NoiseScale("NoiseScale", Float) = 0.5
		_NoiseShift("NoiseShift", Float) = 0.5
	}
	SubShader
	{
		Pass
		{
			CGPROGRAM

			#pragma vertex vert
			#pragma fragment frag
			#pragma target 4.0
			#pragma only_renderers d3d11

			#include "UnityCG.cginc"
			#include "Permutation.cginc"
			#include "Gradient.cginc"
			
			float _UVScale;
			float _UVShift;
			float _NoiseScale;
			float _NoiseShift;

			float2 fade(float2 t)
			{
				return t*t*t*(t*(t*6-15)+10);
			}

			float perlinNoise2(float2 xy)
			{
				// Find unit square that contains point and find relative x,y of point in square
				float2 ij = floor(xy);
				xy -= ij;

				// Compute fade curves for each of x,y
				float2 uv = fade(xy);

				// Hash coordinates at the 4 square corners
				float4 perm = perm2(ij);

				// Sample gradients at the 4 square corners (normalised to the range [-1, 1])
				float4 g0 = grad2(perm.xy);
				float4 g1 = grad2(perm.zw);

				// Compute gradient ramp at the 4 square corners
				float g00 = dot2(g0.xy, xy+float2( 0,  0));
				float g10 = dot2(g0.zw, xy+float2(-1,  0));
				float g01 = dot2(g1.xy, xy+float2( 0, -1));
				float g11 = dot2(g1.zw, xy+float2(-1, -1));

				// Blend the results along x
				float nx0 = lerp(g00, g10, uv.x);
				float nx1 = lerp(g01, g11, uv.x);

				// Blend the results along y
				float nxy = lerp(nx0, nx1, uv.y);

				// Return the result, roughly normalised to the range [-1, 1]
				return nxy;
			}

			struct v2f
			{
				float4 pos : POSITION;
				float2 uv : TEXCOORD0;
			};

			v2f vert(appdata_base v)
			{
				v2f o;
				o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
				o.uv = v.texcoord.xy;
				return o;
			}

			float4 frag(v2f i) : COLOR
			{
				return perlinNoise2(i.uv*_UVScale+_UVShift)*_NoiseScale+_NoiseShift;
			}

			ENDCG
		}
	}
	Fallback Off
}